package com.bwie.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bwie.es.ESProd;
import com.bwie.mapper.CarMapper;
import com.bwie.mapper.ProdMapper;
import com.bwie.pojo.Car;
import com.bwie.pojo.Prod;
import com.bwie.utils.R;
import com.bwie.vo.PageInfoVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @Author GaoYiJie
 * @Description
 * @Create 2025/3/1 8:30
 * @Version 1.0
 */
@Service
public class ProdServiceImpl implements ProdService {

    @Autowired
    ProdMapper prodMapper;

    @Autowired
    CarMapper carMapper;

    @Autowired
    HttpServletRequest request;

    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public R getEsProdByPage(PageInfoVo pageInfoVo) {
        //构造分页参数
        if (pageInfoVo.getPageNum() > 0){
            pageInfoVo.setPageNum(pageInfoVo.getPageNum()-1);
        }
        PageRequest pageRequest = PageRequest.of(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        //构造查询条件  条件查询+高亮
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if (!StringUtils.isEmpty(pageInfoVo.getProdName())){
            boolQueryBuilder.must(
                    QueryBuilders.matchQuery("prodName",pageInfoVo.getProdName())
            );
        }
        if (!StringUtils.isEmpty(pageInfoVo.getBeginTime()) && !StringUtils.isEmpty(pageInfoVo.getEndTime())){
            boolQueryBuilder.must(
              QueryBuilders.rangeQuery("createTime")
                      .format("yyyy-MM-dd HH:mm:ss")
                      .timeZone("GMT+8")
                      .gte(pageInfoVo.getBeginTime())
                      .lte(pageInfoVo.getEndTime())
            );
        }

        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("prodName").preTags("<font color='red'>").postTags("</font>");

        //排序
        FieldSortBuilder fieldSortBuilder = new FieldSortBuilder("saleNum");
        fieldSortBuilder.order(SortOrder.DESC);

        //将分页参数和条件整合
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder)
                .withHighlightBuilder(highlightBuilder)
                .withSort(fieldSortBuilder)
                .withPageable(pageRequest);

        //查询数据
        SearchHits<ESProd> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), ESProd.class);

        //读取数据
        long total = search.getTotalHits();
        ArrayList<ESProd> records = new ArrayList<>();
        for (SearchHit<ESProd> searchHit : search.getSearchHits()) {
            ESProd prod = searchHit.getContent();
            //获取高亮字段
            List<String> prodNameHigh = searchHit.getHighlightField("prodName");
            if (!prodNameHigh.isEmpty()){
                String prodName = prodNameHigh.get(0);
                //替换
                prod.setProdName(prodName);
            }

            records.add(prod);
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("total",total);
        map.put("records",records);


        return R.OK(map);
    }

    @Override
    public R addBuyCar(Car car) {
        //判断是否存在
        Car carDB = carMapper.selectOne(new QueryWrapper<Car>().lambda().eq(Car::getProdId, car.getProdId()).last("limit 1"));
        if (carDB == null){
            //新增购物车
            String token = request.getHeader("token");
            Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
            Integer userId = body.get("userId", Integer.class);

            car.setUserId(userId);
            car.setCarProdNum(1);

            carMapper.insert(car);
            return R.OK();
        }

        //修改数量
        carDB.setCarProdNum(carDB.getCarProdNum()+1);
        carMapper.updateById(carDB);
        return R.OK();
    }

    @Override
    public R getProdList() {
        List<Prod> prods = prodMapper.selectList(null);
        return R.OK(prods);
    }

    @Override
    public R updateProd(Prod prod) {
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
    System.out.println(prod);
        prodMapper.updateById(prod);
        return R.OK();
    }
}
